概述
在上一篇文章中,我们对于事件在Activity之前的传递我们并没有详细的介绍,那么本文就详细来介绍一下这部分事件传递流程。
Activity的事件来源是和 ViewRootImpl 密切相关的。
事件传递流程
当用户点击屏幕产生一个触摸行为,这个触摸行为则是通过底层硬件来传递捕获,然后交给ViewRootImpl,接着将事件传递给DecorView,而DecorView再交给PhoneWindow,PhoneWindow再交给Activity,然后接下来就是我们前面介绍的常见的View事件分发了。
我们用下面的流程来简单描述一下:
1 | 硬件 |
InputEventReceiver
ViewRootImpl 中实例化了一个 InputEventReceiver 对象来接收输入事件,然后交给ViewRootImpl来进行处理。
1 | // ViewRootImpl.java |
1 | final class WindowInputEventReceiver extends InputEventReceiver { |
1 | void enqueueInputEvent(InputEvent event, |
1 | void doProcessInputEvents() { |
1 | private void deliverInputEvent(QueuedInputEvent q) { |
这里InputStage则是一个实现处理输入事件责任的阶段,它是一个基类,也就是说InputStage提供一系列处理输入事件的方法,也可以转发给其他事件处理,而具体的处理则是看它的实现类。每种InputStage可以处理一定的事件类型,比如AsyncInputStage、ViewPreImeInputStage、ViewPostImeInputStage等。当一个InputEvent到来时,ViewRootImpl会寻找合适它的InputStage来处理。
InputStage的处理情况为,会先调用deliver开始处理。
1 | public final void deliver(QueuedInputEvent q) { |
最终的事件分发处理则是在apply方法里的onProcess方法。
对于点击事件来说,InputState的子类ViewPostImeInputStage可以处理它,我们看下ViewPostImeInputStage的onProcess方法。
1 | final class ViewPostImeInputStage extends InputStage { |
ViewPostImeInputStage.processPointerEvent -> DecorView.dispatchPointerEvent -> DecorView.dispatchTouchEvent
1 | @Override |
这里的 cb 其实就是 Activity,在 attach() 方法中注册的回调:
1 | final void attach(......) { |
那么接下来就由 Activity 来处理了。